import * as vscode from "vscode";
import { login, logout } from "@ap/user/accountsLogin";
import { setAPIType } from "@ap/util/request";
import { setFilePath } from "@ap/util/vscode/getFilePath";
import path from "path";
import { showWarningMessage } from "@ap/util/vscode/message";
import { setHMRToolStatus } from "@ap/tools/hmr";
import {
  setMapStorageValue,
  warmDataStorageConfig,
} from "@ap/user/map/setMapStorage";
import { getMapStorageList, validJson } from "@ap/user/map/getMapStorage";
import { CommandId, storageMapTreeDataProvider } from "@ap/command";
import { getESCCfg, insertComponent } from "@ap/util/mapFile/componentPresets";
import { mcpServer } from "@ap/tools/mcp";
import { onlyKnowledgeBase } from "@ap/webView/chatDialog";
import * as z from "zod";

export function onAllEvents(context: vscode.ExtensionContext): void {
  // 监听URI事件
  context.subscriptions.push(
    vscode.window.registerUriHandler({
      handleUri(uri: vscode.Uri) {
        const queryParams = new URLSearchParams(uri.query);
        if (uri.fsPath === "/command") {
          const type = queryParams.get("type");
          const rest = queryParams.get("rest")?.split(",");
          if (type) {
            vscode.commands.executeCommand(type, ...(rest || []));
          }
        }
      },
    }),
  );

  // 监听文件创建事件
  context.subscriptions.push(
    vscode.workspace.onDidCreateFiles(async (event) => {
      const ecsCfg = await getESCCfg();
      if (ecsCfg.client || ecsCfg.server) {
        event.files.forEach(async (fileUri) => {
          insertComponent(fileUri, ecsCfg);
        });
      }
    }),
  );

  //监听设置文件配置变化
  context.subscriptions.push(
    vscode.workspace.onDidChangeConfiguration((event) => {
      // 检查是否影响了用户中心工具的账户令牌配置
      if (
        event.affectsConfiguration("userCenterTool.AccountToken") ||
        event.affectsConfiguration("userCenterTool.UserAgnet")
      ) {
        login();
      }
      // 检查是否影响了平台环境配置
      if (event.affectsConfiguration("nodeJsTool.Box3APIType")) {
        setAPIType();
        logout();
      }
    }),
  );

  // 监听当前活动的文本编辑器变化
  context.subscriptions.push(
    vscode.window.onDidChangeActiveTextEditor((event) => {
      // 当有编辑器被更变时，更新文件路径
      if (event) {
        setFilePath(event).then(() => {
          setHMRToolStatus();
        });
      }
    }),
  );

  // 监听当前活动的文本编辑器保存时
  context.subscriptions.push(
    vscode.workspace.onDidSaveTextDocument(
      async (document: vscode.TextDocument) => {
        const fileName = path.basename(document.uri.fsPath);
        if (
          fileName === "GameAPI.d.ts" ||
          fileName === "ClientAPI.d.ts" ||
          fileName === "dao3-ap.code-snippets"
        ) {
          showWarningMessage(
            "请勿手动修改" +
              fileName +
              "，因插件具有自动检测更新机制，发现差异将拉取云端文件并覆盖本地文件。",
          );
        }
        if (
          fileName === "GameAssets.d.ts" ||
          fileName === "dao3-GameAssets.code-snippets"
        ) {
          showWarningMessage(
            "请勿手动修改" +
              fileName +
              "，避免资源与地图不同步可能导致的错误。",
          );
        }
        if (fileName.includes("Arena数据空间")) {
          if (!warmDataStorageConfig()) {
            return;
          }
          const regex = /^(.*?) - (.*)$/;
          const match = fileName.match(regex);
          if (match && match[1]) {
            await setMapStorageValue({
              key: match[1],
              value: validJson(document.getText()),
            });
            await getMapStorageList();
            storageMapTreeDataProvider.refresh();
          }
        }
      },
    ),
  );
}

/**
 * 注册命令
 * @param command 命令名称
 * @param callback 回调函数
 * @returns 注册的命令
 */
export function registerCommand(
  command: string,
  name: string,
  callback: (...args: any[]) => any,
  thisArg?: any,
) {
  // 保留的核心命令列表
  const essentialCommands: CommandId[] = [
    CommandId.userCenterTool_userTokenAndUA,
    CommandId.userCenterTool_userInfo,
    CommandId.userCenterTool_accountsLogin,
    CommandId.userCenterTool_accountsLogout,
    CommandId.file_npm_package_get,
    CommandId.file_outputName,
    CommandId.file_mapTool,
    CommandId.file_buildNUpload,
    CommandId.file_createProject,
    CommandId.file_checkDts,
    CommandId.file_nodeJs_setting,
    CommandId.file_openArena,
    CommandId.file_reHMR,
    CommandId.file_stopHMR,
    CommandId.file_upLoad,
    CommandId.file_debugger,
    CommandId.file_openOutputLog,
    CommandId.file_dao3config_open,
    CommandId.file_npm_package_path,
    CommandId.map_showMap,
    CommandId.map_playData,
    CommandId.map_resource,
    CommandId.component_showComponentStats,
  ];

  if (essentialCommands.includes(command as CommandId)) {
    mcpServer.tool(
      command.replace(/\./g, "_"),
      name,
      {},
      async (extra: any) => {
        try {
          const result = await vscode.commands.executeCommand(
            command,
            extra?.args,
          );

          return {
            content: [
              {
                type: "text",
                text: result ? JSON.stringify(result) : "执行完成",
              },
            ],
          };
        } catch (error) {
          return {
            content: [
              {
                type: "text",
                text: (error as Error).message,
              },
            ],
          };
        }
      },
    );
  }

  return vscode.commands.registerCommand(command, callback, thisArg);
}

mcpServer.tool(
  "ap_chatjpt_onlyKnowledgeBase",
  "查询神岛API知识库内容，并返回筛选后的知识数据",
  { msg: z.string().describe("要查询的知识") },
  async ({ msg }: { msg: string }) => {
    const result = await onlyKnowledgeBase(msg);
    return {
      content: [
        {
          type: "text",
          text: result ? JSON.stringify(result) : "查询失败",
        },
      ],
    };
  },
);
